package com.tuanzi.loan.business.service.receipt.statistics.impl;

import com.tuanzi.loan.business.entity.extend.ExtendInfo;
import com.tuanzi.loan.business.entity.receipt.order.ReceiptOrder;
import com.tuanzi.loan.business.entity.receipt.product.ReceiptProductInfo;
import com.tuanzi.loan.business.repository.receipt.statistics.impl.ReceiptOrderStatisticsRepositoryImpl;
import com.tuanzi.loan.business.service.extend.ExtendInfoService;
import com.tuanzi.loan.business.service.receipt.order.ReceiptOrderService;
import com.tuanzi.loan.business.service.receipt.product.ReceiptProductInfoService;
import com.tuanzi.loan.business.service.receipt.statistics.ReceiptBalanceOperationRecordService;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.tuanzi.loan.business.entity.receipt.statistics.ReceiptOrderStatistics;
import com.tuanzi.loan.business.repository.receipt.statistics.ReceiptOrderStatisticsRepository;
import com.tuanzi.loan.business.service.receipt.statistics.ReceiptOrderStatisticsService;
import com.tuanzi.loan.core.aspect.Debug;
import com.tuanzi.loan.core.service.CommonServiceImpl;
import com.tuanzi.loan.core.vo.PageSearcher;
import com.tuanzi.loan.vo.request.receipt.statistics.ReceiptOrderStatisticsRequest;
import com.tuanzi.loan.vo.response.receipt.statistics.ReceiptOrderStatisticsResponse;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Debug
@Service
@Transactional
public class ReceiptOrderStatisticsServiceImpl extends CommonServiceImpl<ReceiptOrderStatistics, Long> implements ReceiptOrderStatisticsService {

	@Autowired
	private ReceiptOrderStatisticsRepository orderStatisticsRepository;
	@Autowired
	private ReceiptOrderService receiptOrderService;
	@Autowired
	private ReceiptProductInfoService receiptProductInfoService;
	@Autowired
	private ExtendInfoService extendInfoService;
	@Autowired
	private ReceiptBalanceOperationRecordService balanceOperationRecordService;

	public static final String BO_LUO_DAI_CHANNEL_ID = "9999";
	public static final String BO_LUO_DAI_CHANNEL_NAME = "菠萝贷";

	@Override
	public Page<ReceiptOrderStatisticsResponse> list(PageSearcher<ReceiptOrderStatisticsRequest> pageSearcher) {
		return orderStatisticsRepository.list(pageSearcher.getSearchCondition(), pageSearcher.getPageable());
	}


	@Override
	public List<ReceiptOrderStatistics> getReceiptStatisticsListByBetweenTime(Date start, Date end) {
		List<ReceiptOrderStatistics> orderStatisticsList = new ArrayList<>();
		//根据产品和订单来源和渠道Id进行分组,第一个层，key是产品id
		Map<Long, Map<Integer, Map<String, List<ReceiptOrder>>>> ordersGroupByProAndSouF = receiptOrderService.findAllByCommitTimeBetween(start, end).stream()
				.collect(Collectors.groupingBy(ReceiptOrder::getProductId, Collectors.groupingBy(ReceiptOrder::getSourceFrom,Collectors.groupingBy(ReceiptOrder::getChannelId))));
		for (Map.Entry<Long, Map<Integer, Map<String, List<ReceiptOrder>>>> productGroupEntry : ordersGroupByProAndSouF.entrySet()) {
			//根据产品id查询产品名称
			ReceiptProductInfo productInfo = receiptProductInfoService.findOne(productGroupEntry.getKey());
			//第二层遍历，key是订单来源
			for (Map.Entry<Integer, Map<String, List<ReceiptOrder>>> sourceFromGroupEntry : productGroupEntry.getValue().entrySet()) {

				//如果订单来源是甲方外推的话，根据产品id来查询所有的外推渠道
				ReceiptOrderStatistics receiptOrderStatistics;
				if (sourceFromGroupEntry.getKey() == ReceiptOrderStatisticsRepositoryImpl.SourceFromType.JIA_FANG_EXTEND.getSourceFromId()) {
					List<ExtendInfo> extendInfos = extendInfoService.findExtendInfoByProductId(productInfo.getId());
					//第三层遍历，key是渠道id
					for (Map.Entry<String, List<ReceiptOrder>> channelGroupEntry : sourceFromGroupEntry.getValue().entrySet()) {
						receiptOrderStatistics = newReceiptOrderStatistics();
						receiptOrderStatistics.setProductId(productInfo.getId());
						receiptOrderStatistics.setProductName(productInfo.getName());
						receiptOrderStatistics.setDate(start);
						receiptOrderStatistics.setOrderCount(Long.valueOf(channelGroupEntry.getValue().size()));
						receiptOrderStatistics.setSourceFrom(sourceFromGroupEntry.getKey());
						receiptOrderStatistics.setChannelId(channelGroupEntry.getKey());
						receiptOrderStatistics.setChannelName(getChannelNameByChannelId(extendInfos,receiptOrderStatistics.getChannelId()));
						for (ReceiptOrder receiptOrder : channelGroupEntry.getValue()) {
							calcStatistic(receiptOrderStatistics,receiptOrder);
						}
						orderStatisticsList.add(receiptOrderStatistics);
					}
				}else{
					receiptOrderStatistics = newReceiptOrderStatistics();
					receiptOrderStatistics.setProductId(productInfo.getId());
					receiptOrderStatistics.setProductName(productInfo.getName());
					receiptOrderStatistics.setDate(start);
					receiptOrderStatistics.setOrderCount(Long.valueOf(sourceFromGroupEntry.getValue().get(BO_LUO_DAI_CHANNEL_ID).size()));
					receiptOrderStatistics.setSourceFrom(sourceFromGroupEntry.getKey());
					receiptOrderStatistics.setChannelId(BO_LUO_DAI_CHANNEL_ID);
					receiptOrderStatistics.setChannelName(BO_LUO_DAI_CHANNEL_NAME);
					for (ReceiptOrder receiptOrder : sourceFromGroupEntry.getValue().get(BO_LUO_DAI_CHANNEL_ID)) {
						calcStatistic(receiptOrderStatistics, receiptOrder);
					}

					//计算结算金额
					Long amount = balanceOperationRecordService.findSettleAmountByProductIdAndSourceFrom(productInfo.getId(), sourceFromGroupEntry.getKey(), start,end);
					receiptOrderStatistics.setSettleAmount(-amount);
					orderStatisticsList.add(receiptOrderStatistics);
				}
			}
		}

		return orderStatisticsList;
	}

	@Override
	public void statisticsTodayReceiptOrder() {
		DateTime now = new DateTime(new Date());
		Date start = new DateTime(now.getYear(), now.getMonthOfYear(), now.getDayOfMonth(), 0, 0, 0).toDate();
		Date end = new DateTime(now.getYear(), now.getMonthOfYear(), now.getDayOfMonth(), 23, 59, 59).toDate();
		List<ReceiptOrderStatistics> receiptStatisticsList = getReceiptStatisticsListByBetweenTime(start, end);
		saveByDate(receiptStatisticsList);
	}

	@Override
	public void saveByDate(List<ReceiptOrderStatistics> receiptOrderStatisticsList) {
		if(receiptOrderStatisticsList == null || receiptOrderStatisticsList.size() <= 0){
			return;
		}

		orderStatisticsRepository.deleteAllByDate(receiptOrderStatisticsList.get(0).getDate());
		orderStatisticsRepository.save(receiptOrderStatisticsList);
	}

	@Override
	protected JpaRepository<ReceiptOrderStatistics, Long> getRepository() {
		return orderStatisticsRepository;
	}



	//根据渠道id查询渠道名称
	private String getChannelNameByChannelId(List<ExtendInfo> extendInfos, String channelId) {
		for (ExtendInfo extendInfo : extendInfos) {
			if (extendInfo.getId().equals(channelId)) {
				return extendInfo.getChannelName();
			}
		}
		return "";
	}

	//在遍历分组的时候，根据订单状态统计相对应的信息
	private void calcStatistic(ReceiptOrderStatistics receiptOrderStatistics, ReceiptOrder receiptOrder) {
		switch (receiptOrder.getStatus()) {
			case WAITING_AUDIT:
				receiptOrderStatistics.setWaitingCount(receiptOrderStatistics.getWaitingCount() + 1);
				break;
			case AUDITING:
				receiptOrderStatistics.setApprovingCount(receiptOrderStatistics.getApprovingCount() + 1);
				break;
			case APPROVE_PASS:
				receiptOrderStatistics.setApprovePassCount(receiptOrderStatistics.getApprovePassCount() + 1);
				break;
			case APPROVE_REJECT:
				receiptOrderStatistics.setRejectCount(receiptOrderStatistics.getRejectCount() + 1);
				break;
			case LOAN_AFTER_LEND_MONEY:
				receiptOrderStatistics.setLoanedCount(receiptOrderStatistics.getLoanedCount() + 1);
				break;
			case LOAN_AFTER_CANCEL_LEND_MONEY:
				receiptOrderStatistics.setCancelCount(receiptOrderStatistics.getCancelCount() + 1);
				break;
		}
	}

	private ReceiptOrderStatistics newReceiptOrderStatistics() {
		ReceiptOrderStatistics receiptOrderStatistics = new ReceiptOrderStatistics();
		receiptOrderStatistics.setApprovingCount(0L);
		receiptOrderStatistics.setApprovePassCount(0L);
		receiptOrderStatistics.setLoanedCount(0L);
		receiptOrderStatistics.setOrderCount(0L);
		receiptOrderStatistics.setWaitingCount(0L);
		receiptOrderStatistics.setRejectCount(0L);
		receiptOrderStatistics.setCancelCount(0L);
		receiptOrderStatistics.setSettleAmount(0L);
		return receiptOrderStatistics;
	}
}
